package auth

import (
	"fmt"
	"huijing_mall/internal/cachebase"
	"huijing_mall/internal/database/models"
	"huijing_mall/shared/common"
	"huijing_mall/shared/get_ctx_value"
	"huijing_mall/shared/kernel/hmErrors"
	"huijing_mall/variable"
	"net/http"
	"strconv"
	"strings"

	"github.com/bytedance/sonic"

	"huijing_mall/pkg/logger"
)

// 验证 verifyCookie
func VerifyCookie(DBS *get_ctx_value.DBS, cookies []*http.Cookie) (uid uint, verify bool) {
	var reqCookie string
	for _, cookie := range cookies {
		if cookie.Name != variable.CookieKey {
			continue
		} else {
			reqCookie = cookie.Name + "=" + cookie.Value
		}
	}
	logger.Info("reqCookie：" + reqCookie)
	if reqCookie == "" {
		return 0, false
	}
	if !strings.HasPrefix(reqCookie, variable.CookieKey) || !strings.Contains(reqCookie, variable.CookieKey) {
		return 0, false
	}
	var TokenArray []string
	var token string
	if strings.Contains(reqCookie, "-") {
		TokenArray = strings.Split(reqCookie, "-")
		if len(TokenArray[1:len(TokenArray)-1]) > 1 {
			for i, v := range TokenArray[1 : len(TokenArray)-1] {
				if i == 0 {
					token += v
				} else {
					token += "-" + v
				}
			}
		} else {
			token = TokenArray[1 : len(TokenArray)-1][0]
		}
		logger.Info(fmt.Sprintf("reqToken：%v", token))
	}
	//最后解析 token
	uid, expiresAt := ParseToken(token)
	if uid == 0 {
		logger.Info("空数据或恶意数据...返回")
		return 0, false
	}
	logger.Info("reqToken ExpiresAt:", strconv.FormatInt(expiresAt, 10))
	logger.Info("reqUid:", uid)

	//最后在比对下
	tokenKey := common.StrPinJie(common.IntToStr(int(uid)), variable.TokenKey)
	if cachebase.RedisExist(DBS.Rdb, tokenKey) {
		Token, err := cachebase.RedisGet(DBS.Rdb, tokenKey)
		if err != nil {
			logger.Error("cachebase token nil")
			return 0, false
		}
		logger.Info("redisToken：" + Token)
		if token != Token {
			return 0, false
		}
	} else {
		return 0, false
	}
	return uid, true
}

func ByUidGetUserInfo(dbs get_ctx_value.DBS, uid uint) (userInfo *models.User, err error) {
	userdataKey := common.StrPinJie(strconv.Itoa(int(uid)), variable.UserDtaKey)
	userCURD := models.NewModelCRUD(models.UserType)
	var res string
	if cachebase.RedisExist(dbs.Rdb, userdataKey) {
		res, err = cachebase.RedisGet(dbs.Rdb, userdataKey)
		if err != nil {
			logger.Error("cachebase userdata nil", err.Error())
			return &models.User{}, hmErrors.SystemTimeOutErr
		}
		sonic.Unmarshal([]byte(res), &userInfo)
	} else {
		err = userCURD.GetByID(dbs.DB, uid)
		//userInfo, err = database.GetUserInfoByUid(dbs.DB, uid)
		if err != nil {
			logger.Error(err.Error())
			return &models.User{}, hmErrors.SystemTimeOutErr
		}
		userInfo, err = models.AssertModelCRUD[*models.User](userCURD)
		if err != nil {
			logger.Error(err.Error())
			return &models.User{}, hmErrors.SystemTypeErr
		}
	}
	return userInfo, nil
}
